package com.yansl.http.handler;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.yansl.http.intercepter.HttpIntercepter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @description: Http网络请求处理
 * @author: eshengtai
 * @create: 2021-09-24 15:06
 */

@Slf4j
public class HttpCallHandler {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 普通请求，特殊请求头处理
     *
     * @param url
     * @param paramMap
     * @param headMaps
     * @param function
     * @param <T>
     * @return
     */
    public <T> T request(HttpMethod httpMethod, String url, Map<String, Object> paramMap, Map<String, String> headMaps, Function<String, T> function,
                    HttpIntercepter httpIntercepter) {

        ParameterizedTypeReference<String> typeRef = new ParameterizedTypeReference<String>() {
        };

        url = httpIntercepter.requestUrl(url);
        boolean isRequest = httpIntercepter.requestBefore(httpMethod, url, paramMap);

        if (isRequest) {
            ResponseEntity<String> httpResult = restTemplate.exchange(url, httpMethod, getEntity(paramMap, headers -> {
                for (String s : headMaps.keySet()) {
                    headers.add(s, headMaps.get(s));
                }
                // 设置请求头
                headers = httpIntercepter.requestHeads(headers);
            }), typeRef, Objects.isNull(paramMap) ? new HashMap<>(0) : paramMap);
            log.info("getRequest => url:{},paramMap:{},headMaps:{},response:{}", url, paramMap, httpResult);

            String responseBody = httpIntercepter.requestAfter(httpResult);
            boolean isResponseJson = StrUtil.isNotBlank(responseBody) && JSONUtil.isJson(responseBody);
            return isResponseJson ? function.apply(responseBody) : (T) responseBody;
        }
        return null;
    }

    /**
     * 设定请求头（Header）
     * 
     * @param t
     * @param consumerHeader
     * @param <T>
     * @return
     */
    private <T> HttpEntity<T> getEntity(T t, Consumer<HttpHeaders> consumerHeader) {
        // 请求头
        HttpHeaders headers = getDefaultHeader();

        // 自定义请求头
        consumerHeader.accept(headers);

        return Objects.isNull(t) ? new HttpEntity<T>(headers) : new HttpEntity<T>(t, headers);
    }

    /**
     * 设置默认请求头
     */
    private HttpHeaders getDefaultHeader() {
        HttpHeaders headers = new HttpHeaders();
        /*通用设置*/
        headers.add("user-agent",
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
        return headers;
    }
}
